<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>react项目部分</title>
        <script>
            function dec2bin(value) {
                let dec = value;
                let bin = '';
                while (dec > 0) {
                    if (dec % 2 != 0) {
                        bin = '1' + bin;
                    } else {
                        bin = '0' + bin;
                    }
                    dec = parseInt(dec / 2);
                }
                return bin;
            }
        </script>
        <script>
            // 187000000 为100ms
            function consumeFun(max, mark) {
                console.time(mark);
                let num = 0;
                const maxFlag = 187000000 * max;
                while (true) {
                    ++num;
                    if (num > maxFlag) break;
                }
                console.timeEnd(mark);
            }
            // console.time('consumeFun');
            // consumeFun(5);
            // console.timeEnd('consumeFun');
        </script>
    </head>
    <body>
        <div style="display: flex">
            <div style="width: 220px;">
                <div id="react-root"></div>
                <div>
                    <button onclick="generateTree()">generateTree</button>
                </div>
                <div id="node-info"></div>
            </div>
            <div id="analysis-root"></div>
        </div>
    </body>

    <script src="./node_modules/@antv/g6/dist/g6.min.js"></script>
    <script>
        const generateUUID = () => {
            let d = new Date().getTime();
            const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                const r = (d + Math.random() * 16) % 16 | 0;
                d = Math.floor(d / 16);
                return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
            });
            return uuid;
        };
    </script>
    <script>
        function renderFiberTree(data) {
            const container = document.getElementById('analysis-root');
            const width = 500;
            const height = 800;
            const graph = new G6.TreeGraph({
                container: 'analysis-root',
                width,
                height,
                linkCenter: true,
                modes: {
                    default: [
                        {
                            type: 'collapse-expand',
                            onChange: function onChange(item, collapsed) {
                                const data = item.get('model').data;
                                data.collapsed = collapsed;
                                return true;
                            },
                        },
                        'drag-canvas',
                        'zoom-canvas',
                    ],
                },
                defaultNode: {
                    size: 50,
                    anchorPoints: [
                        [0, 0.5],
                        [1, 0.5],
                    ],
                },
                defaultEdge: {
                    type: 'cubic-vertical',
                },
                layout: {
                    type: 'compactBox',
                    direction: 'TB',
                    getId: function getId(d) {
                        return d.id;
                    },
                    getHeight: function getHeight() {
                        return 16;
                    },
                    getWidth: function getWidth() {
                        return 16;
                    },
                    getVGap: function getVGap() {
                        return 80;
                    },
                    getHGap: function getHGap() {
                        return 120;
                    },
                },
            });

            graph.node(function (node) {
                let position = 'right';
                let rotate = 0;
                if (!node.children) {
                    position = 'bottom';
                    rotate = Math.PI / 2;
                }
                return {
                    label: node.name,
                    labelCfg: {
                        position,
                        offset: 5,
                        style: {
                            rotate,
                            textAlign: 'start',
                            fontSize: 24,
                        },
                    },
                };
            });

            graph.data(data);
            graph.render();
            graph.fitView();

            // 点击节点
            graph.on('node:mouseenter', (e) => {
                const nodeItem = e.item; // 获取鼠标进入的节点元素对象
                graph.setItemState(nodeItem, 'hover', true); // 设置当前节点的 hover 状态为 true

                console.log('---------nodeItem: ', nodeItem);
                const {
                    _cfg: {
                        model: { name, parent = {}, sibling = '' },
                    },
                } = nodeItem;

                const nodeInfo = {
                    name,
                    parent: parent.name || '',
                    sibling,
                };
                document.getElementById('node-info').innerText = JSON.stringify(nodeInfo, null, 4);
            });
        }
    </script>

    <script>
        function generateTree() {
            const fiberNodeTreeDom = document.getElementById('react-root');
            const rootFiberNode = fiberNodeTreeDom[window.internalContainerInstanceKey];

            console.log('rootFiberNode: ', rootFiberNode);
            const treeData = {
                // id: rootFiberNode.stateNode.constructor.name,
            };

            const getChildren = (data, tempData) => {
                const parent = data.return;
                const child = data.child;
                const sibling = data.sibling;

                tempData.id = generateUUID();
                tempData.name = data.stateNode.nodeName || data.stateNode.constructor.name;

                console.log('-------tempData: ', tempData);

                // const parentTemp = {};
                // if (parent) {
                //     parentTemp
                //     parentTemp.id = parent.stateNode.nodeName || parent.stateNode.constructor.name;
                //     parentTemp.children = [];
                //     // tempData.parent = parentTemp;
                // }

                const newChild = {};
                if (child) {
                    newChild.id = generateUUID();
                    newChild.name = child.stateNode.nodeName || child.stateNode.constructor.name;
                    newChild.parent = tempData;
                    if (tempData.children) {
                        tempData.children.push(newChild);
                    } else {
                        tempData.children = [newChild];
                    }

                    getChildren(child, newChild);
                }

                const newSibling = {};
                if (sibling) {
                    newSibling.id = generateUUID();
                    newSibling.name =
                        sibling.stateNode.nodeName || sibling.stateNode.constructor.name;
                    // console.log('---tempData.parent: ', tempData);
                    newSibling.parent = tempData.parent;
                    tempData.sibling =
                        sibling.stateNode.nodeName || sibling.stateNode.constructor.name;
                    if (tempData.parent.children) {
                        tempData.parent.children.push(newSibling);
                    } else {
                        tempData.parent.children = [newSibling];
                    }
                    getChildren(sibling, newSibling);
                }
            };

            getChildren(rootFiberNode, treeData);

            console.log('treeData: ', treeData);
            renderFiberTree(treeData);
        }
    </script>
</html>
